from lib.server.http import response
from lib.log.index import server_logger
from lib.config.index import server_config


async def handle_client(reader, writer):
    peername = writer.get_extra_info("peername")
    if server_config.is_debug():
        print("New client connected...")
    while True:
        try:
            chunk = await reader.read(1024)
            # print(chunk)
            if len(chunk) == 0:
                break
            # print("receive: ", chunk)
            chunk_str = chunk.decode("utf8")
            await handle_http(chunk_str, writer, peername)
        except Exception as e:
            if server_config.is_debug():
                import sys

                sys.print_exception(e)
            break
    writer.close()
    await writer.wait_closed()


async def get_http_headers(chunk_lines):
    header_line = chunk_lines[0]

    if not header_line:
        return None

    parts = header_line.split(" ")
    if len(parts) != 3:
        return None

    method = parts[0]
    path = parts[1]
    protocol = parts[2]

    return (method, path, protocol)


async def handle_http(chunk, writer, peername):
    chunk_lines = chunk.split("\r\n")
    headers = await get_http_headers(chunk_lines)

    if not headers:
        if server_config.is_debug():
            print("error: ", chunk)
        await response.return_error(writer, "/")
        return

    (method, path, protocol) = headers
    (ip, port) = peername
    info = {"protocol": protocol, "ip": ip, "port": port}

    server_logger.log(method, path, info)

    if method == "GET":
        await handle_GET(path, writer)

    if method == "POST":
        await handle_POST(path, writer)

    await writer.drain()
    writer.close()


async def handle_GET(path, writer):
    if path == "/":
        return await response.visit_root(writer, path)

    if path.startswith("/api"):
        return await response.visit_api(writer, path)

    return await response.visit_file(writer, path)


async def handle_POST(path, writer):
    pass
